/**
* @file EphFileReader.cpp
* Class to handle interpolatable time serial data
*/

//============================================================================
//
//  Shoujian Zhang, Wuhan University, 2019.4.25
//
//============================================================================

#include "StringUtils.hpp"
#include "EphFileReader.hpp"
#include "MiscMath.hpp"
#include "CommonTime.hpp"
#include "MJD.hpp"
#include <fstream>

using namespace std;
using namespace gpstk::StringUtils;

#define debug 1

namespace gpstk
{

   void EphFileReader::loadEPH()
      noexcept(false)
   {
       try
       {
           ////////////////////////////////////////
           // Read and load sp3 files
           ////////////////////////////////////////
           ifstream ephInpf( ephIdxFile.c_str());
           if(!ephInpf)
           {
              FileMissingException fme("Could not open eph files " + ephIdxFile);
              GPSTK_THROW(fme);
           }

              // Now, read the leap second data
           while(!ephInpf.eof() && ephInpf.good())
           {
              string line;
              getline(ephInpf,line);
              StringUtils::stripTrailing(line,'\r');

              if( ephInpf.eof() ) break;
              if( ephInpf.bad() ) break;

              if(debug)
              {
                 cout << "line:" << line << endl;
              }

                 // Jump the header!
              if(line[0] == '#') continue;

                 // Define a string stream to read 'line'
              istringstream istrm(line);

              string ephFile;

                 // Get the variable values from stream
              istrm >> ephFile;


                 // read sp3 files
              pSP3Store->loadSP3File(ephFile);

           }

           ephInpf.close();

       }
       catch(Exception& e)
       {
           cerr << e << endl;
           exit(-1);
       }
       catch(...)
       {
           cerr << "Unknown Eph file ERROR!" << endl;
           exit(-1);
       }

           ////////////////////////////////////////
           // Read and load clk files
           ////////////////////////////////////////

       try
       {
           ifstream clkInpf( clkIdxFile.c_str());
           if(!clkInpf)
           {
              FileMissingException fme("Could not open clk files " + clkIdxFile);
              GPSTK_THROW(fme);
           }

              // Now, read the leap second data
           while(!clkInpf.eof() && clkInpf.good())
           {
              string line;
              getline(clkInpf,line);
              StringUtils::stripTrailing(line,'\r');

              if( clkInpf.eof() ) break;
              if( clkInpf.bad() ) break;

              if(debug)
              {
                 cout << "line:" << line << endl;
              }

                 // Jump the header!
              if(line[0] == '#') continue;

                 // Define a string stream to read 'line'
              istringstream istrm(line);

              string clkFile;

                 // Get the variable values from stream
              istrm >> clkFile;

                 // read sp3 files
              pSP3Store->loadRinexClockFile(clkFile);

           }

           clkInpf.close();
       }
       catch(Exception& e)
       {
           cerr << e << endl;
           exit(-1);
       }
       catch(...)
       {
           cerr << "clk file ERROR!" << endl;
           exit(-1);
       }

           ////////////////////////////////////////
           //
           // Read and load dcb files
           //
           ////////////////////////////////////////

       try
       {

           ifstream dcbInpf( dcbIdxFile.c_str());
           if(!dcbInpf)
           {
              FileMissingException fme("Could not open dcb files " + dcbIdxFile);
              GPSTK_THROW(fme);
           }

              // Now, read dcb data
           while(!dcbInpf.eof() && dcbInpf.good())
           {
              string line;
              getline(dcbInpf,line);
              StringUtils::stripTrailing(line,'\r');

              if( dcbInpf.eof() ) break;
              if( dcbInpf.bad() ) break;

              if(debug)
              {
                 cout << "line:" << line << endl;
              }

                 // Jump the header!
              if(line[0] == '#') continue;

                 // Define a string stream to read 'line'
              istringstream istrm(line);

              string dcbFile;

                 // Get the variable values from stream
              istrm >> dcbFile;

                 // read sp3 files
              pMGEXDCBStore->open(dcbFile);

           }

           dcbInpf.close();
       }
       catch(Exception& e)
       {
           cerr << e << endl;
           exit(-1);
       }
       catch(...)
       {
           cerr << "dcb file ERROR!" << endl;
           exit(-1);
       }
   }
           ////////////////////////////////////////
           // Read and load ifcb files
           ////////////////////////////////////////

   int EphFileReader::loadIFCB()
      noexcept(false)
   {
       try
       {


           ifstream ifcbInpf( ifcbIdxFile.c_str());
           if(!ifcbInpf)
           {
              FileMissingException fme("Could not open ifcb files " + ifcbIdxFile);
              GPSTK_THROW(fme);
           }

           int nfiles(0);
              // Now, read ifcb data
           while(!ifcbInpf.eof() && ifcbInpf.good())
           {
              string line;
              getline(ifcbInpf,line);
              StringUtils::stripTrailing(line,'\r');

              if( ifcbInpf.eof() ) break;
              if( ifcbInpf.bad() ) break;

              if(debug)
              {
                 cout << "line:" << line << endl;
              }

                 // Jump the header!
              if(line[0] == '#') continue;

                 // Define a string stream to read 'line'
              istringstream istrm(line);

              string ifcbFile;

                 // Get the variable values from stream
              istrm >> ifcbFile;

              nfiles++;

                 // read sp3 files
              pIFCBStore->loadFile(ifcbFile);

           }

           ifcbInpf.close();

           return nfiles;
       }
       catch(FileMissingException& e)
       {
           cerr << e << endl;;
       }
       catch(Exception& e)
       {
           cerr << e << endl;
           exit(-1);
       }
       catch(...)
       {
           cerr << "ifcb file ERROR!" << endl;
           exit(-1);
       }

   }

           ////////////////////////////////////////
           //
           // Read and load msc files
           //
           ////////////////////////////////////////
   void EphFileReader::loadMSC()
      noexcept(false)
   {
       try
       {
           ifstream mscInpf( mscIdxFile.c_str());
           if(!mscInpf)
           {
              FileMissingException fme("Could not open msc files " + mscIdxFile);
              GPSTK_THROW(fme);
           }

              // Now, read the leap second data
           while(!mscInpf.eof() && mscInpf.good())
           {
              string line;
              getline(mscInpf,line);
              StringUtils::stripTrailing(line,'\r');

              if( mscInpf.eof() ) break;
              if( mscInpf.bad() ) break;

              if(debug)
              {
                 cout << "line:" << line << endl;
              }

                 // Jump the header!
              if(line[0] == '#') continue;

                 // Define a string stream to read 'line'
              istringstream istrm(line);

              string mscFile;

                 // Get the variable values from stream
              istrm >> mscFile;

                 // read sp3 files
              pMSCStore->loadFile(mscFile);

           }

           mscInpf.close();

           ////////////////////////////////////////

       }
       catch(Exception& e)
       {
           cerr << e << endl;
           exit(-1);
       }
       catch(...)
       {
           cerr << "msc file ERROR!" << endl;
           exit(-1);
       }

       return;
   }

   void EphFileReader::loadDCB()
      noexcept(false)
   {
           ////////////////////////////////////////
           //
           // Read and load dcb files
           //
           ////////////////////////////////////////

       try
       {

           ifstream dcbInpf( dcbIdxFile.c_str());
           if(!dcbInpf)
           {
              FileMissingException fme("Could not open dcb files " + dcbIdxFile);
              GPSTK_THROW(fme);
           }

              // Now, read dcb data
           while(!dcbInpf.eof() && dcbInpf.good())
           {
              string line;
              getline(dcbInpf,line);
              StringUtils::stripTrailing(line,'\r');

              if( dcbInpf.eof() ) break;
              if( dcbInpf.bad() ) break;

              if(debug)
              {
                 cout << "line:" << line << endl;
              }

                 // Jump the header!
              if(line[0] == '#') continue;

                 // Define a string stream to read 'line'
              istringstream istrm(line);

              string dcbFile;

                 // Get the variable values from stream
              istrm >> dcbFile;

                 // read sp3 files
              pMGEXDCBStore->open(dcbFile);

           }

           dcbInpf.close();
       }
       catch(Exception& e)
       {
           cerr << e << endl;
           exit(-1);
       }
       catch(...)
       {
           cerr << "dcb file ERROR!" << endl;
           exit(-1);
       }

       return;
   }

}  // End of namespace gpstk
